package ch.zbw.timeline.service;

import java.rmi.Remote;
import java.rmi.RemoteException;
import java.sql.Time;
import java.util.Calendar;
import java.util.List;

import ch.zbw.timeline.domain.Statistic;
import ch.zbw.timeline.domain.Allocation;
import ch.zbw.timeline.domain.DailyPresence;
import ch.zbw.timeline.domain.Employee;
import ch.zbw.timeline.domain.Entry;
import ch.zbw.timeline.domain.HolidayFormula;
import ch.zbw.timeline.domain.LogEntry;
import ch.zbw.timeline.domain.OverTimePool;
import ch.zbw.timeline.domain.Period;
import ch.zbw.timeline.domain.Process;
import ch.zbw.timeline.domain.Role;
import ch.zbw.timeline.domain.Task;
import ch.zbw.timeline.domain.YearConfig;

/**
 * Interface that handles communication between
 * Server and Client
 * 
 * @author Daniel Stefanovic
 * @version 26.01.2012
 * 
 */
public interface ServerService extends Remote {

	/**
	 * Sets up the connection between client and server.
	 * 
	 * @param url 
	 * @return server service
	 * @throws Exception
	 */
	public ServerService connectToServer(String url) throws Exception;
	
	/**
	 * Starts the server.
	 * 
	 * @throws RemoteException
	 */
	public void startServer() throws RemoteException;

	/**
	 * Returns a list with all available roles from repository.
	 * 
	 * @return list with all roles
	 * @throws RemoteException
	 */
	public List<Role> getAllRoles() throws RemoteException;

	/**
	 * Authenticates the user.
	 * 
	 * @param userName user name
	 * @param password password
	 * @param role selected role
	 * @return employee object
	 * @throws RemoteException
	 */
	public Employee authenticate(String userName, String password, Role role) throws RemoteException;

	/**
	 * Returns a daily presence by employee and day from repository.
	 * 
	 * @param employee employee
	 * @param day day of presence
	 * @return daily presence object
	 * @throws RemoteException
	 */
	public DailyPresence getDailyPresence(Employee employee, Calendar day) throws RemoteException;

	/**
	 * Returns all entries of a daily presence from repository.
	 * 
	 * @param presence daily presence
	 * @return list of entries
	 * @throws RemoteException
	 */
	public List<Entry> getAllEntries(DailyPresence presence) throws RemoteException;

	/**
	 * Returns a list with all employees from repository.
	 * 
	 * @return list with all employees
	 * @throws RemoteException
	 */
	public List<Employee> getAllEmployees() throws RemoteException;

	/**
	 * Endcodes a string with md5
	 * 
	 * @param text text to encode
	 * @return encoded text
	 * @throws RemoteException
	 */
	public String generateMd5(String text) throws RemoteException;
	
	/**
	 * Saves an employee object to repository.
	 * 
	 * @param employee employee to save
	 * @return saved employee
	 * @throws RemoteException
	 */
	public Employee saveEmployee(Employee employee) throws RemoteException;

	/**
	 * Creates an employee object and saves it to repository.
	 * 
	 * @param firstName first name
	 * @param lastName last name
	 * @param userName user name
	 * @param commencementDate commencement date
	 * @param password password
	 * @param dateOfBirth date of birth
	 * @param role role
	 * @param employmentStatus employment status
	 * @param active is user active?
	 * @return created employee
	 * @throws RemoteException
	 */
	public Employee createEmployee(String firstName, String lastName, String userName, Calendar commencementDate,
			String password, Calendar dateOfBirth, Role role, int employmentStatus, boolean active) throws RemoteException;

	/**
	 * Returns a list with all available processes from repository.
	 * 
	 * @return list with all processes
	 * @throws RemoteException
	 */
	public List<Process> getAllProcesses() throws RemoteException;

	/**
	 * Saves an process to repository.
	 * 
	 * @param process process to save
	 * @return saved process
	 * @throws RemoteException
	 */
	public Process saveProcess(Process process) throws RemoteException;

	/**
	 * Creates a process and saves it to repository.
	 * 
	 * @param description process description
	 * @param active is process active?
	 * @return created process
	 * @throws RemoteException
	 */
	public Process createProcess(String description, boolean active) throws RemoteException;

	/**
	 * Saves an task to repository.
	 * 
	 * @param task task to save
	 * @return saved task
	 * @throws RemoteException
	 */
	public Task saveTask(Task task) throws RemoteException;

	/**
	 * Creates a new task and saves it to repository.
	 * 
	 * @param description task description
	 * @param active is task active?
	 * @return created task
	 * @throws RemoteException
	 */
	public Task createTask(String description, boolean active) throws RemoteException;

	/**
	 * Returns a list with all available task from repository.
	 * 
	 * @return list with all tasks
	 * @throws RemoteException
	 */
	public List<Task> getAllTasks() throws RemoteException;

	/**
	 * Saves an allocation to repository.
	 * 
	 * @param allocation allocation to save
	 * @return saved allocation
	 * @throws RemoteException
	 */
	public Allocation saveAllocation(Allocation allocation) throws RemoteException;

	/**
	 * Creates an allocation and saves it to repository.
	 * 
	 * @param process process for allocation
	 * @param task task for allocation
	 * @param active is allocation active?
	 * @return created allocation
	 * @throws RemoteException
	 */
	public Allocation createAllocation(Process process, Task task, boolean active) throws RemoteException;

	/**
	 * Return a list with all available allocations from repository.
	 * 
	 * @return list with all allocation
	 * @throws RemoteException
	 */
	public List<Allocation> getAllAllocations() throws RemoteException;

	/**
	 * Saves an holiday formula to repository.
	 * 
	 * @param holidayFormula holiday formula to save
	 * @return saved holiday formula
	 * @throws RemoteException
	 */
	public HolidayFormula saveHolidayFormula(HolidayFormula holidayFormula) throws RemoteException;

	/**
	 * Creates a holiday formula and saves it to repository.
	 * 
	 * @param description formula description
	 * @param formula formula
	 * @return created formula
	 * @throws RemoteException
	 */
	public HolidayFormula createHolidayFormula(String description, String formula) throws RemoteException;

	/**
	 * Return a list with all available holiday formulas from repository.
	 * 
	 * @return list with all holiday formulas
	 * @throws RemoteException
	 */
	public List<HolidayFormula> getAllHolidayFormulas() throws RemoteException;

	/**
	 * Saves an overtime pool to repository.
	 * 
	 * @param overTimePool overtime pool to save
	 * @return saved overtime pools
	 * @throws RemoteException
	 */
	public OverTimePool saveOverTimePool(OverTimePool overTimePool) throws RemoteException;

	/**
	 * Creates an overtime pool and saves it to repository.
	 * 
	 * @param employee overtime pool employee
	 * @param numberOfHours number of hours
	 * @param description overtime pool description
	 * @return created overtime pool
	 * @throws RemoteException
	 */
	public OverTimePool createOverTimePool(Employee employee, double numberOfHours, String description) throws RemoteException;

	/**
	 * Returns a list with all overtime pools
	 * 
	 * @return list with all overtime pools
	 * @throws RemoteException
	 */
	public List<OverTimePool> getAllOverTimePools() throws RemoteException;

	/**
	 * Returns a list with all log entries
	 * 
	 * @return list with all log entries
	 * @throws RemoteException
	 */
	public List<LogEntry> getAllLogEntries() throws RemoteException;

	/**
	 * Returns a list of all yearConfigs
	 * 
	 * @return list of all yearConfigs
	 * @throws RemoteException
	 */
	public List<YearConfig> getAllYearConfigs() throws RemoteException;

	/**
	 * Saves a yearConfig to the database
	 * 
	 * @param yearConfig YearConfig
	 * @return the given yearConfig
	 * @throws RemoteException
	 */
	public YearConfig saveYearConfig(YearConfig yearConfig) throws RemoteException;

	/**
	 * Returns a list of all allocations by the given employee 
	 *  
	 * @param employee employee
	 * @return list of allocations from the given employee
	 * @throws RemoteException
	 */
	public List<Allocation> getOverTimePoolAllocations(Employee employee) throws RemoteException;

	/**
	 * Returns a list of the used hours from the overtimepool from the given employee
	 * 
	 * @param employee employee
	 * @return list of all used overtimepool hours
	 * @throws RemoteException
	 */
	public double getOverTimePoolHoursUsed(Employee employee) throws RemoteException;

	/**
	 * Saves the given dailyPresence object to the databse
	 * 
	 * @param dailyPresence daily presence
	 * @return the given dailyPresence
	 * @throws RemoteException
	 */
	public DailyPresence saveDailyPresence(DailyPresence dailyPresence) throws RemoteException;

	/**
	 * Returns the total presence time of the given dailyPresence object
	 * 
	 * @param presence daily presence
	 * @return total time of the dailyPresence
	 * @throws RemoteException
	 */
	public Time getPresenceTimeTotal(DailyPresence presence) throws RemoteException;

	/**
	 * Returns the total time of unused hours from the given dailypresnece
	 * 
	 * @param presence daily presence
	 * @return the total time of unused hours
	 * @throws RemoteException
	 */
	public Time getPresenceTimeUnused(DailyPresence presence) throws RemoteException;

	/**
	 * Creates and saves an entry object to the database
	 * 
	 * @param dailyPresence daily presence
	 * @param duration dutation of the entry
	 * @param allocation allocation of the entry
	 * @param comment comment of the entry
	 * @param overTimePool overtimepool
	 * @return the created entry object 
	 * @throws RemoteException
	 */
	public Entry createEntry(DailyPresence dailyPresence, double duration, Allocation allocation, String comment,
			OverTimePool overTimePool) throws RemoteException;

	/**
	 * Returns the overtimepool from the given employee
	 * 
	 * @param employee
	 * @return overtimepool
	 * @throws RemoteException
	 */
	public OverTimePool getOverTimePool(Employee employee) throws RemoteException;

	/**
	 * Creates and saves a dailyPresence object to the databse
	 * 
	 * @param employee employee of the dailyPresence
	 * @param dateOfPresence date of presence
	 * @param morningStart start hour in the morning
	 * @param morningEnd end hour in the morning
	 * @param afternoonStart start hour in the afternoon
	 * @param afternoonEnd end hour in the afternoon
	 * @param morningVacation morning is vacation or not
	 * @param afternoonVacation afternoon is vacation or not
	 * @return the created dailyPressence object
	 * @throws RemoteException
	 */
	public DailyPresence createDailyPresence(Employee employee, Calendar dateOfPresence, Calendar morningStart,
			Calendar morningEnd, Calendar afternoonStart, Calendar afternoonEnd, boolean morningVacation,
			boolean afternoonVacation) throws RemoteException;

	/**
	 * Saves the entry to the database
	 * 
	 * @param entry
	 * @return given entry
	 * @throws RemoteException
	 */
	public Entry saveEntry(Entry entry) throws RemoteException;

	/**
	 * Delete the given entry from the database
	 * 
	 * @param entry entry that has to be deleted
	 * @throws RemoteException
	 */
	public void deleteEntry(Entry entry) throws RemoteException;

	/**
	 * Returns all periods form the given year
	 * 
	 * @param year
	 * @return returns list of periods
	 * @throws RemoteException
	 */
	public List<Period> getPeriods(int year) throws RemoteException;

	/**
	 * Generates the statistic from teh given employee and the given period
	 * 
	 * @param employee employee
	 * @param period period from which the statistic should be generated
	 * @return returns the generated statistic
	 * @throws RemoteException
	 */
	public Statistic generateStatistic(Employee employee, Period period) throws RemoteException;

	/**
	 * Checks if year config is used
	 * 
	 * @param yearConfigId Id of year config
	 * @return is used?
	 */
	public boolean isYearUsed(int yearConfigId) throws RemoteException;
}
